<template>
  <div class="container">
    <div class="app-container">
      <!-- data：指定渲染的内容的数据
      default-expand-all: 默认展开所有节点
      expand-on-click-node: 点击箭头的时候才展开或收起子节点
       -->
      <el-tree
        :data="treeData"
        :props="defalutProps"
        :expand-on-click-node="false"
        default-expand-all
      >
        <!-- 自定义树形控件结构：可以使用作用域插槽实现
        data: 是作用域插槽传回的数据对象
         -->
        <template v-slot="{data}">
          <el-row style="width: 100%">
            <!-- el-col 表示列，elementui中把一行分为24列
            通过span属性合并列 -->
            <el-col :span="20"> {{ data.name }} </el-col>
            <el-col :span="4">
              <span>{{ data.managerName }}</span>
              <!-- 下拉菜单 -->
              <el-dropdown>
                <!-- 渲染在页面上的内容 -->
                <span>
                  操作<i class="el-icon-arrow-down el-icon--right" />
                </span>
                <!-- 下拉菜单部分 -->
                <template v-slot:dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click.native="add(data.id)">添加子部门</el-dropdown-item>
                    <el-dropdown-item @click.native="edit(data.id)">编辑部门</el-dropdown-item>
                    <el-dropdown-item @click.native="del(data.id)">删除</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </el-col>
          </el-row>
        </template>
      </el-tree>
      <!-- 新增部门 -->
      <AddDepts
        ref="depts"
        :show-dialog.sync="isShow"
        :dept-id="curId"
        @updateEvent="getList"
      />
    </div>
  </div>
</template>
<script>
/**
 * 需求1：组织架构列表渲染
 * 1、封装接口函数
 * 2、在created中调用接口，请求并保存数据
 * 3、根据数据渲染
 *    难点 --- 数据转换 --- 递归函数实现
 *
 * 需求2：新增子部门
 * 分析：点击“添加子部门”按钮，显示弹窗，弹窗有部门表单信息，
 * 用户输入部门相关信息，最后点击“确定”按钮，实现新增
 * 拆解步骤：
 * 1、给“添加子部门”按钮绑定点击事件
 * 2、准备好一个dialog组件实现弹窗 --- 难点 封装成单独组件
 * 3、在点击事件处理函数中控制弹窗的显示
 * 4、实现弹窗的布局和表单校验
 *     难点 --- 自定义校验规则 -部门名称和编码不能和已存在的重复
 * 5、收集用户输入的表单内容 -- v-model
 * 6、给“确定”按钮绑定点击事件，声明事件处理函数
 * 7、封装新增子部门的接口函数
 * 8、在确定的事件处理函数中调用接口，实现新增
 *
 * 需求3：编辑部门
 * 分析：点击“编辑部门”按钮，显示弹窗，弹窗中的内容自动回显，用户修改内容，
 * 最后点击确定按钮，实现修改。
 * 根据分析拆解实现步骤：
 * 1、给“编辑部门”按钮绑定点击事件
 * 2、准备弹窗 --- 直接复用新增的弹窗即可 已完成
 * 3、在点击事件的处理函数中控制弹窗显示即可
 * 4、弹窗内容的回显
 *     难点 ---- 内容回显 --思路：调用接口获取部门信息-赋值给formData
 * 5、收集用户修改后的内容 -- v-model  已完成
 * 6、给“确定”按钮绑定点击事件 --- 已完成
 * 7、封装修改部门信息的接口函数
 * 8、在确定的事件处理函数中调用接口函数，实现修改
 *
 * 需求4：弹窗标题的动态渲染
        1、利用3元运算符 + formData.id进行动态渲染
        注意：关闭弹窗的时候需要把fromData.id也清空，
        这样判断才不会有问题。
 *
 * 需求5：实现删除部门
 * 分析：点击删除部门按钮，显示询问框，点击确定按钮实现删除
 * 拆解步骤：
 * 1、给“删除部门”按钮绑定点击事件
 * 2、在事件处理函数中控制询问框的显示 --- confirm方法
 *     --- 询问框作用：防止用户误删 -- 提高用户体验
 * 3、给“确定”按钮绑定点击 --- 无需绑定，直接使用elementUI提供的方法即可
 * 4、封装删除接口函数
 * 5、在确定的事件处理函数中调用删除接口函数即可
 *
 * */
import { departmentList, deleteDept } from '@/api/department'
import { transListToTreeData } from '@/utils'
import AddDepts from './components/AddDepts'
export default {
  components: { AddDepts },
  data() {
    return {
      treeData: [
        {
          name: '传智教育',
          managerName: '管理员',
          children: [
            {
              name: '总裁办',
              managerName: '小黄'
            },
            {
              name: '技术部',
              managerName: '小明'
            }
          ]
        }
      ],
      defalutProps: {
        // label: 指定渲染内容的属性名
        label: 'name',
        // children：指定渲染子级的属性名
        children: 'children'
      },
      isShow: false, // 控制弹窗组件的显示隐藏
      curId: null // 当前选择部门的id
    }
  },
  created() {
    this.getList()
  },
  methods: {
    // 获取组织架构列表
    async getList() {
      this.treeData = await departmentList()
      // 列表转树形结构
      // 判断父子关系：pid的值等于另一个对象id的值 说明他们是父子关系
      // 顶级部门: pid的值为0的时候，说明该部门为顶级部门
      this.treeData = transListToTreeData(this.treeData, 0)
    },
    // 新增
    add(id) {
      this.curId = id
      this.isShow = true
    },
    // 编辑
    edit(id) {
      this.add(id)
      // 父组件调用子组件的函数 -- ref
      // console.log(this.$refs.depts)
      this.$nextTick(() => {
        // 因为dom更新是异步的，所以id传给子组件也是异步的
        // 因此需要等待dom更新结束后再调用子组件函数
        this.$refs.depts.getDeptDetails()
      })
    },
    // 删除部门
    del(id) {
      this.$confirm('您确定要删除该部门吗？', '提示', {
        // 按钮的文本
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning' // 文本内容左边图标
      }).then(async() => {
        // console.log('您点击了确定按钮')
        await deleteDept(id)
        this.$message.success('删除成功')
        // 更新部门列表
        this.getList()
      }).catch(() => {
        console.log('您点击了取消按钮')
      })
    }
  }
}
</script>
<style scoped>
.app-container{
  padding: 30px 140px;
  font-size: 14px;
}
.el-dropdown {
  margin-left: 20px;
}
</style>
